home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / editor / gdphrc14.lha / ged-phrasecomp / PhraseCompletion.c < prev    next >
C/C++ Source or Header  |  1996-04-27  |  19KB  |  792 lines

  1. /*
  2. ** $PROJECT: GoldED Phrase-Completion API-Client
  3. **
  4. ** $VER: PhraseCompletion.c 1.4 (27.04.96)
  5. **
  6. ** by
  7. **
  8. ** Stefan Ruppert , Windthorststrasse 5 , 65439 Floersheim , GERMANY
  9. **
  10. ** (C) Copyright 1996
  11. ** All Rights Reserved !
  12. **
  13. ** $HISTORY:
  14. **
  15. ** 27.04.96 : 001.004 : completion didn't worded, if word was at the beginning of a line (fixed)
  16. ** 14.04.96 : 001.003 : now uses WHITESPACES arg to get the word to expand
  17. ** 24.02.96 : 001.002 : searches now in the line of the cursor
  18. ** 09.02.96 : 001.001 : separated in a own program
  19. **
  20. */
  21.  
  22. /*FS*//* --------------------------- version defines ---------------------------- */
  23.  
  24. /* $STARTDEFINE: "BumpRev defines"*/
  25. #define VERSION  1
  26. #define REVISION 4
  27. #define DATE "27.4.96"
  28. #define VERS "PhraseCompletion 1.4"
  29. #define VSTRING "PhraseCompletion 1.4 (27.4.96)\r\n"
  30. #define VERSTAG "\0$VER: PhraseCompletion 1.4 (27.4.96)"
  31. #define NAME "PhraseCompletion"
  32. #define PROJECTNAME "PhraseCompletion: "
  33.  
  34. /* $ENDDEFINE:   */
  35. /*FE*/
  36.  
  37. /*FS*//* ------------------------------- include -------------------------------- */
  38.  
  39. #define __USE_SYSBASE
  40.  
  41. #include <string.h>
  42. #include <ctype.h>
  43.  
  44. #include <exec/types.h>
  45. #include <exec/memory.h>
  46.  
  47. #include <dos/dos.h>
  48.  
  49. #include <rexx/errors.h>
  50.  
  51. #include <proto/exec.h>
  52. #include <proto/dos.h>
  53. #include <proto/utility.h>
  54. #include <proto/rexxsyslib.h>
  55.  
  56. #include <clib/alib_protos.h>
  57. #include <clib/alib_stdio_protos.h>
  58.  
  59. #include "golded:api/include/golded.h"
  60.  
  61. #include "debug.h"
  62. #include "register.h"
  63. /*FE*/
  64.  
  65. /*FS*//* ------------------------------- AutoDoc -------------------------------- */
  66.  
  67. /*GB*** GoldED-API/PharseCompletion ******************************************
  68.  
  69.      $VER: PharseCompletion.doc 1.4 (27.4.96)
  70.  
  71.      NAME
  72.           PhraseCompletion
  73.  
  74.      VERSION
  75.           1.4
  76.  
  77.      DESCRIPTION
  78.           Just run GoldED and load this as an API-Client ! Then you have the
  79.           following new ARexx command :
  80.  
  81.      TEMPLATE
  82.           PHRASECOMPLETION WHITESPACES,MAX/N,CASE/S,BACKWARD/S,ALL/S
  83.  
  84.      FORMAT
  85.           PHRASECOMPLETION [[WHITESPACES] whitespace-characters] [[MAX] number]
  86.                                  [CASE] [BACKWARD] [ALL]
  87.  
  88.      DESCRIPTION
  89.           The PHRASECOMPLETION ARexx command provides you a new phrase
  90.           completion method. It extracts the actual word-phrase (before cursor)
  91.           and tries to complete this phrase. This is done by searching in the
  92.           buffers for a word beginning with this extracted phrase. The first
  93.           found is displayed in the buffer. If there are more than one words
  94.           matching the phrase, you can step through all found words by just
  95.           using this command again with same cursor position. If the last word
  96.           is reached a ERROR_NO_MORE_ENTRIES error code is returned and then it
  97.           starts again with the first word.
  98.  
  99.      INPUTS
  100.           WHITESPACES -- a string, which represent the characters to use as
  101.                 whitespaces. Default is " \t".
  102.  
  103.           MAX -- maximal number of matching words. Default is ~0.
  104.  
  105.           CASE -- don't ignore case-sensetive. Default is ignore.
  106.  
  107.           BACKWARD -- normaly the buffer is first searched from the actual
  108.                 line to the beginnig and then from actual line to the end of
  109.                 the buffer. This argument swaps the search direction.
  110.  
  111.           ALL -- searchs in all opened buffers
  112.  
  113.      RESULTS
  114.           the command returns RC_OK, if it could complete the pharse. RC_WARN
  115.           if not !
  116.  
  117.      SPECIAL REQUIREMENTS
  118.           Needs GoldED 3.x to run.
  119.  
  120.      AVAILABILITY
  121.           ftp://wuarchive.wustl.edu/pub/aminet/text/edit/GED-PhrCmp1.4.lha
  122.           And all other Aminet sites
  123.  
  124.      AUTHOR
  125.           Stefan Ruppert
  126.           Windthorststrasse 5
  127.           65439 Floersheim
  128.           Germany
  129.  
  130.           Internet:
  131.           ruppert@informatik.fh-wiesbaden.de
  132.           ruppert@goofy.zdv.uni-mainz.de
  133.           http://www.uni-mainz.de/~ruppert
  134.  
  135.      SEE ALSO
  136.           Emacs, GoldED/API
  137.  
  138. *****************************************************************************/
  139. /*FE*/
  140.  
  141. /*FS*//* ------------------------------- defines -------------------------------- */
  142.  
  143. #define PUDDLE_SIZE              4096
  144. #define BUFFER_LEN               512
  145.  
  146. #define PHRASECOMP_ARGS          "WHITESPACES,MAX/N,CASE/S,BACKWARD/S,ALL/S"
  147.  
  148. #define MAX_PARAMETER            6
  149.  
  150. #define EOS                      '\0'
  151.  
  152. #define USETAG(tag,check)        ((check) ? (tag) : TAG_IGNORE)
  153.  
  154. /*FE*/
  155.  
  156. /*FS*//* ----------------------------- structures ------------------------------- */
  157.  
  158. struct RexxCommands
  159. {
  160.     STRPTR rxc_Command;
  161.     LONG (*rxc_Handler) (struct GlobalData *,struct APIMessage *);
  162.     STRPTR rxc_Template;
  163. };
  164.  
  165. struct GlobalData
  166. {
  167.     struct Library *gd_SysBase;
  168.     struct Library *gd_DOSBase;
  169.     struct Library *gd_UtilityBase;
  170.     struct Library *gd_RexxSysBase;
  171.  
  172.     APTR gd_Pool;
  173.     APTR gd_FoundPool;
  174.  
  175.     struct MsgPort *gd_ApiPort;
  176.     struct MsgPort *gd_RexxPort;
  177.  
  178.     STRPTR gd_GoldEDHost;
  179.  
  180.     ULONG gd_Result;
  181.     LONG gd_Found;
  182.  
  183.     struct List gd_FoundList;
  184.     struct Node *gd_LastFound;
  185.  
  186.     ULONG gd_Para[MAX_PARAMETER];
  187.  
  188.     ULONG gd_Len;
  189.     ULONG gd_Max;
  190.     UBYTE gd_Buffer[BUFFER_LEN];
  191.     UBYTE gd_Name[BUFFER_LEN];
  192.     UBYTE gd_LastName[BUFFER_LEN];
  193.  
  194.     struct APIModifyRequest gd_Modify;
  195. };
  196. /*FE*/
  197.  
  198. /*FS*//* ------------------------------ prototypes ------------------------------ */
  199.  
  200. void search_command(struct GlobalData *gd,struct APIMessage *msg);
  201.  
  202. LONG RexxCmd_PhraseComp(struct GlobalData *gd,struct APIMessage *msg);
  203.  
  204. BOOL send_rexxcommand(struct GlobalData *gd,STRPTR cmd);
  205. BOOL alloc_name(struct GlobalData *gd,STRPTR name,LONG len);
  206.  
  207. RegCall void *AsmCreatePool(REGD0 ULONG ,REGD1 ULONG ,REGD2 ULONG ,REGA6 struct Library *);
  208. RegCall void AsmDeletePool(REGA0 APTR ,REGA6 struct Library *);
  209. RegCall void *AsmAllocPooled(REGA0 APTR ,REGD0 ULONG ,REGA6 struct Library *);
  210. RegCall void AsmFreePooled(REGA0 APTR ,REGA1 APTR ,REGD0 ULONG ,REGA6 struct Library *);
  211.  
  212. /*FE*/
  213.  
  214. /*FS*//* -------------------------- static data items --------------------------- */
  215.  
  216. static const STRPTR version = VERSTAG;
  217. static const STRPTR prgname = NAME;
  218.  
  219. static struct RexxCommands rexxcmd[] = {
  220.     {"PHRASECOMPLETION",RexxCmd_PhraseComp,PHRASECOMP_ARGS},
  221.     {NULL}};
  222.  
  223. static struct TagItem apitags[] = {
  224.     {API_Client_Name       ,(ULONG) NAME},
  225.     {API_Client_Copyright  ,(ULONG) "©1996 Stefan Ruppert"},
  226.     {API_Client_Purpose    ,(ULONG) VERS "\n\nPhrase completion\nthrough all buffers"},
  227.     {API_Client_Template   ,(ULONG) "PHRASECOMPLETION " PHRASECOMP_ARGS},
  228.     {TAG_DONE,0}};
  229. /*FE*/
  230.  
  231. /*FS*//* ------------------------- template definition -------------------------- */
  232.  
  233. #define template    "HOST/K/A"
  234.  
  235. enum {
  236.     ARG_HOST,
  237.     ARG_MAX};
  238. /*FE*/
  239.  
  240. /* --------------------------- main entry point --------------------------- */
  241.  
  242. /*FS*/GetA4 int main(void)
  243. {
  244.     struct Library *SysBase = *((struct Library **) 4L);
  245.     struct Library *DOSBase;
  246.     struct RDArgs *args;
  247.     LONG para[ARG_MAX];
  248.     STRPTR obj = prgname;
  249.     LONG rc = RETURN_OK;
  250.  
  251.     LONG i;
  252.  
  253.     /* clear args buffer */
  254.     for(i = 0 ; i < ARG_MAX ; i++)
  255.         para[i] = 0;
  256.  
  257.     if((DOSBase = OpenLibrary("dos.library",37)) != NULL)
  258.     {
  259.         LONG err = 0;
  260.  
  261.         if((args = ReadArgs(template,para,NULL)) != NULL)
  262.         {
  263.             APTR pool;
  264.  
  265.             if((pool = AsmCreatePool(MEMF_CLEAR | MEMF_ANY, PUDDLE_SIZE, PUDDLE_SIZE,SysBase)) != NULL)
  266.             {
  267.                 struct GlobalData *gd;     
  268.  
  269.                 DB(("golded host : %s\n",para[ARG_HOST]));
  270.                 if((gd = AsmAllocPooled(pool,sizeof(struct GlobalData),SysBase)) != NULL)
  271.                 {
  272.                     gd->gd_Pool = pool;
  273.  
  274.                     gd->gd_SysBase = SysBase;
  275.                     gd->gd_DOSBase = DOSBase;
  276.  
  277.                     gd->gd_UtilityBase   = OpenLibrary("utility.library",37);
  278.                     gd->gd_RexxSysBase   = OpenLibrary("rexxsyslib.library",36);
  279.  
  280.                     NewList(&gd->gd_FoundList);
  281.  
  282.                     if(gd->gd_UtilityBase != NULL && gd->gd_RexxSysBase != NULL)
  283.                     {
  284.                         if((gd->gd_ApiPort = CreateMsgPort()))
  285.                         {
  286.                             if((gd->gd_RexxPort = CreateMsgPort()))
  287.                             {
  288.                                 gd->gd_GoldEDHost   = (STRPTR)   para[ARG_HOST];
  289.  
  290.                                 sprintf(gd->gd_Buffer,"API PORT=%ld CLASS=%ld",
  291.                                                              gd->gd_ApiPort,
  292.                                                              API_CLASS_ROOT | API_CLASS_REXX);
  293.  
  294.                                 if(send_rexxcommand(gd,gd->gd_Buffer) && gd->gd_Result == RC_OK)
  295.                                 {
  296.                                     struct APIMessage *apimsg;
  297.                                     struct APIMessage *msg;
  298.  
  299.                                     BOOL active = TRUE;
  300.  
  301.                                     DB(("xrefapi active !\n"));
  302.  
  303.                                     do
  304.                                     {
  305.                                         WaitPort(gd->gd_ApiPort);
  306.  
  307.                                         while((apimsg = (struct APIMessage *) GetMsg(gd->gd_ApiPort)))
  308.                                         {
  309.                                             for(msg = apimsg ; msg ; msg = msg->api_Next)
  310.                                             {
  311.                                                 if(msg->api_State == API_STATE_NOTIFY)
  312.                                                 {
  313.                                                     switch(msg->api_Class)
  314.                                                     {
  315.                                                     case API_CLASS_ROOT:
  316.                                                         switch(msg->api_Action)
  317.                                                         {
  318.                                                         case API_ACTION_DIE:
  319.                                                             active = FALSE;
  320.                                                             break;
  321.                                                         case API_ACTION_INTRODUCE:
  322.                                                             msg->api_Data = apitags;
  323.                                                             break;
  324.                                                         }
  325.                                                         break;
  326.                                                     case API_CLASS_REXX:
  327.                                                         switch(msg->api_Action)
  328.                                                         {
  329.                                                         case API_ACTION_COMMAND:
  330.                                                             search_command(gd,msg);
  331.                                                             break;
  332.                                                         default:
  333.                                                             msg->api_Error = API_ERROR_UNKNOWN;
  334.                                                         }
  335.                                                         break;
  336.                                                     default:
  337.                                                         msg->api_Error = API_ERROR_UNKNOWN;
  338.                                                     }
  339.                                                 }
  340.                                             }
  341.  
  342.                                             ReplyMsg((struct Message *) apimsg);
  343.                                         }
  344.                                     } while(active);
  345.                                     SetIoErr(0);
  346.                                 }
  347.                                 DeleteMsgPort(gd->gd_RexxPort);
  348.                             }
  349.                             DeleteMsgPort(gd->gd_ApiPort);
  350.                         }
  351.  
  352.                         if(gd->gd_FoundPool != NULL)
  353.                             AsmDeletePool(gd->gd_FoundPool,SysBase);
  354.                     }
  355.  
  356.                     CloseLibrary(gd->gd_RexxSysBase);
  357.                     CloseLibrary(gd->gd_UtilityBase);
  358.                 }
  359.  
  360.                 AsmDeletePool(pool,SysBase);
  361.             }
  362.             FreeArgs(args);
  363.         }
  364.  
  365.         if(err == 0)
  366.             err = IoErr();
  367.  
  368.         if(err != 0)
  369.         {
  370.             PrintFault(err,obj);
  371.             rc = RETURN_ERROR;
  372.         }
  373.  
  374.         CloseLibrary(DOSBase);
  375.     }
  376.  
  377.     return rc;
  378. }
  379. #define SysBase         gd->gd_SysBase
  380. #define DOSBase         gd->gd_DOSBase
  381. #define UtilityBase     gd->gd_UtilityBase
  382. #define RexxSysBase     gd->gd_RexxSysBase
  383. /*FE*/
  384.  
  385. /* -------------------------- find rexx command --------------------------- */
  386.  
  387. /*FS*/ void search_command(struct GlobalData *gd,struct APIMessage *msg)
  388. {
  389.     struct APIRexxNotify *notify = (struct APIRexxNotify *) msg->api_Data;
  390.     struct RexxCommands  *rxcmd  = rexxcmd;
  391.     LONG len;
  392.  
  393.     notify->arn_RC = RC_WARN;
  394.  
  395.     while(rxcmd->rxc_Command)
  396.     {
  397.         len = strlen(rxcmd->rxc_Command);
  398.  
  399.         if(!strncmp(notify->arn_Command,rxcmd->rxc_Command,len))
  400.         {
  401.             struct RDArgs *rdargs;
  402.             struct RDArgs *args;
  403.             LONG i;
  404.  
  405.             msg->api_State = API_STATE_CONSUMED;
  406.  
  407.             strncpy(gd->gd_Buffer,¬ify->arn_Command[len],BUFFER_LEN);
  408.             strncat(gd->gd_Buffer,"\n",BUFFER_LEN);
  409.  
  410.             if(rdargs = (struct RDArgs *) AllocDosObject(DOS_RDARGS,NULL))
  411.             {
  412.                 rdargs->RDA_Source.CS_Buffer   = gd->gd_Buffer;
  413.                 rdargs->RDA_Source.CS_Length   = strlen(gd->gd_Buffer);
  414.  
  415.                 for(i=0 ; i < MAX_PARAMETER ; i++)
  416.                     gd->gd_Para[i]=0;
  417.  
  418.                 DB(("rdargs at : %lx\n",rdargs));
  419.  
  420.                 if((args = ReadArgs(rxcmd->rxc_Template,(LONG *) gd->gd_Para,rdargs)))
  421.                 {
  422.                     DB(("args at %lx\n",args));
  423.  
  424.                     notify->arn_RC = rxcmd->rxc_Handler(gd,msg);
  425.  
  426.                     FreeArgs(args);
  427.                 }
  428.                 FreeDosObject(DOS_RDARGS , rdargs);
  429.             }
  430.         }
  431.         rxcmd++;
  432.     }
  433.  
  434.     if(notify->arn_RC != RC_OK)
  435.     {
  436.         Fault(IoErr(),NAME,gd->gd_Buffer,BUFFER_LEN);
  437.         notify->arn_CommandError = gd->gd_Buffer;
  438.     }
  439. }
  440. /*FE*/
  441.  
  442. /* ---------------------------- rexx commands ----------------------------- */
  443.  
  444. /*FS*//*"LONG RexxCmd_PhraseComp(struct GlobalData *gd,struct APIMessage *msg)"*/
  445. struct IntArgs
  446. {
  447.     STRPTR ia_WhiteSpaces;
  448.     LONG *ia_Max;
  449.     LONG ia_Case;
  450.     LONG ia_Backward;
  451.     LONG ia_All;
  452. };
  453. /*FS*/ void match_expand(struct GlobalData *gd,struct IntArgs *args,struct LineNode *ln)
  454. {
  455.     STRPTR name;
  456.     STRPTR ptr;
  457.     STRPTR end;
  458.     LONG len;
  459.  
  460.     ptr = ln->Text;
  461.     end = ptr + ln->Len;
  462.  
  463.     if(args->ia_Case)
  464.     {
  465.         do
  466.         {
  467.             while(ptr < end && strchr(args->ia_WhiteSpaces,*ptr) != NULL)
  468.                 ptr++;
  469.  
  470.             name = ptr;
  471.             while(ptr < end && strchr(args->ia_WhiteSpaces,*ptr) == NULL)
  472.                 ptr++;
  473.  
  474.             len = ptr - name;
  475.             if(len > gd->gd_Len)
  476.             {
  477.                 if(!strncmp(name,gd->gd_Buffer,gd->gd_Len))
  478.                 {
  479.                     alloc_name(gd,name,len);
  480.                     if(--gd->gd_Max == 0)
  481.                         break;
  482.                 }
  483.             }
  484.         } while(ptr < end);
  485.     } else
  486.     {
  487.         do
  488.         {
  489.             while(ptr < end && strchr(args->ia_WhiteSpaces,*ptr) != NULL)
  490.                 ptr++;
  491.  
  492.             name = ptr;
  493.             while(ptr < end && strchr(args->ia_WhiteSpaces,*ptr) == NULL)
  494.                 ptr++;
  495.  
  496.             len = ptr - name;
  497.             if(len > gd->gd_Len)
  498.             {
  499.                 if(!Strnicmp(name,gd->gd_Buffer,gd->gd_Len))
  500.                 {
  501.                     alloc_name(gd,name,len);
  502.                     if(--gd->gd_Max == 0)
  503.                         break;
  504.                 }
  505.             }
  506.         } while(ptr < end);
  507.     }
  508.  
  509.     if(ln->Fold != NULL)
  510.     {
  511.         struct LineNode *end;
  512.         len = ln->Fold->Lines;
  513.         ln  = ln->Fold->TextNodes;
  514.  
  515.         end = ln + len;
  516.         while(ln < end && gd->gd_Max > 0)
  517.         {
  518.             match_expand(gd,args,ln++);
  519.         }
  520.     }
  521.  
  522.     return;
  523. }
  524. /*FE*/
  525.  
  526. LONG RexxCmd_PhraseComp(struct GlobalData *gd,struct APIMessage *msg)
  527. {
  528.     struct EditConfig *ec = msg->api_Config;
  529.     struct LineNode *ln;
  530.     struct IntArgs *args = (struct IntArgs *) gd->gd_Para;
  531.  
  532.     UWORD  column;
  533.     STRPTR wrd;
  534.     STRPTR buf;
  535.     LONG retval = RC_WARN;
  536.  
  537.     gd->gd_Max = ~0;
  538.     if(args->ia_Max != NULL)
  539.         gd->gd_Max = *args->ia_Max;
  540.  
  541.     column = ec->Column;
  542.     buf    = ec->CurrentBuffer;
  543.     wrd    = gd->gd_Buffer;
  544.  
  545.     if(column > 0)
  546.     {
  547.         STRPTR found = NULL;
  548.         STRPTR end   = buf + column;
  549.         STRPTR begin = end - 1;
  550.         LONG foundlen;
  551.         LONG len;
  552.  
  553.         while(begin >= buf && strchr(args->ia_WhiteSpaces,*begin) == NULL)
  554.             begin--;
  555.         begin++;
  556.         column -= (end - begin);
  557.  
  558.         len = end - begin;
  559.  
  560.         if(len == 0)
  561.             SetIoErr(ERROR_REQUIRED_ARG_MISSING);
  562.         else
  563.         {
  564.             movmem(begin,wrd,len);
  565.             wrd[len] = 0;
  566.             gd->gd_Len = len;
  567.  
  568.             DB(("expand : %s\n",wrd));
  569.  
  570.             if(!IsListEmpty(&gd->gd_FoundList) && gd->gd_LastName[0] != '\0' &&
  571.                 !strncmp(gd->gd_LastName,wrd,strlen(gd->gd_LastName)))
  572.             {
  573.                 struct Node *node = gd->gd_LastFound;
  574.  
  575.                 DB(("Get Next word : %lx\n",node));
  576.                 if(node != NULL)
  577.                 {
  578.                     node = node->ln_Succ;
  579.                     if(node->ln_Succ != NULL)
  580.                         gd->gd_LastFound = node;
  581.                     else
  582.                         gd->gd_LastFound = NULL;
  583.                 } else
  584.                     gd->gd_LastFound = gd->gd_FoundList.lh_Head;
  585.  
  586.                 if(gd->gd_LastFound != NULL)
  587.                 {
  588.                     found    = gd->gd_LastFound->ln_Name;
  589.                     foundlen = strlen(found);
  590.                 } else
  591.                     SetIoErr(ERROR_NO_MORE_ENTRIES);
  592.             } else
  593.             {
  594.                 LONG try = 2;
  595.  
  596.                 strcpy(gd->gd_LastName,wrd);
  597.                 if(gd->gd_FoundPool != NULL)
  598.                     AsmDeletePool(gd->gd_FoundPool,SysBase);
  599.                 NewList(&gd->gd_FoundList);
  600.                 gd->gd_LastFound = NULL;
  601.                 gd->gd_FoundPool = AsmCreatePool(MEMF_ANY | MEMF_CLEAR,PUDDLE_SIZE,PUDDLE_SIZE,SysBase);
  602.  
  603.                 if(args->ia_WhiteSpaces == NULL)
  604.                     args->ia_WhiteSpaces = " \t";
  605.  
  606.                 while(try > 0 && gd->gd_Max > 0)
  607.                 {
  608.                     try--;
  609.                     if(args->ia_Backward)
  610.                     {
  611.                         struct LineNode *end = ec->TextNodes + ec->Lines;
  612.                         ln = &ec->TextNodes[ec->Line]+1;
  613.                         while(ln < end && gd->gd_Max > 0)
  614.                             match_expand(gd,args,ln++);
  615.                     } else
  616.                     {
  617.                         ULONG len;
  618.  
  619.                         ln = &ec->TextNodes[ec->Line];
  620.                         /* cut current line to the cursor pos */
  621.                         len = ln->Len;
  622.                         ln->Len = ec->Column-1;
  623.                         match_expand(gd,args,ln);
  624.                         ln->Len = len;
  625.                         ln--;
  626.  
  627.                         while(ln >= ec->TextNodes && gd->gd_Max > 0)
  628.                             match_expand(gd,args,ln--);
  629.                     }
  630.                     args->ia_Backward = !args->ia_Backward;
  631.                 }
  632.  
  633.                 if(args->ia_All && gd->gd_Max > 0)
  634.                 {
  635.                     struct EditConfig *first = ec;
  636.  
  637.                     while(first->Node.ln_Pred != NULL)
  638.                         first = (struct EditConfig *) first->Node.ln_Pred;
  639.  
  640.                     first = (struct EditConfig *) first->Node.ln_Succ;
  641.  
  642.                     while(first->Node.ln_Succ != NULL && gd->gd_Max > 0)
  643.                     {
  644.                         struct LineNode *end = first->TextNodes + first->Lines;
  645.                         DB(("name : %s\n",first->Name));
  646.  
  647.                         if(first != ec)
  648.                         {
  649.                             ln = first->TextNodes;
  650.                             while(ln < end && gd->gd_Max > 0)
  651.                                 match_expand(gd,args,ln++);
  652.                         }
  653.  
  654.                         first = (struct EditConfig *) first->Node.ln_Succ;
  655.                     }
  656.  
  657.                 }
  658.  
  659.                 if(gd->gd_FoundList.lh_Head->ln_Succ != NULL)
  660.                 {
  661.                     struct Node *node = gd->gd_FoundList.lh_Head;
  662.  
  663.     #if 0
  664.                     if(args->ia_Select)
  665.                         node = select_node(gd,&gd->gd_FoundList,msg->api_Global->F_ScrnName);
  666.     #endif
  667.  
  668.                     if(node != NULL)
  669.                     {
  670.                         gd->gd_LastFound = node;
  671.                         found = node->ln_Name;
  672.                         foundlen = strlen(found);
  673.                     } else
  674.                       SetIoErr(ERROR_OBJECT_NOT_FOUND);
  675.                 } else
  676.                   SetIoErr(ERROR_OBJECT_NOT_FOUND);
  677.             }
  678.  
  679.             DB(("found = \"%s\" , len : %ld\n",found,foundlen));
  680.             if(found != NULL && foundlen > 0)
  681.             {
  682.                 strncpy(gd->gd_LastName,found,foundlen);
  683.                 gd->gd_LastName[foundlen] = '\0';
  684.  
  685.                 strncpy(gd->gd_Buffer,ec->CurrentBuffer,column);
  686.                 strncpy(&gd->gd_Buffer[column],found,foundlen);
  687.                 strcpy(&gd->gd_Buffer[column + foundlen],ec->CurrentBuffer + ec->Column);
  688.                 gd->gd_Modify.mr_Next   = NULL;
  689.                 gd->gd_Modify.mr_Line   = ec->Line;
  690.                 gd->gd_Modify.mr_Column = column + foundlen;
  691.                 gd->gd_Modify.mr_Data   = gd->gd_Buffer;
  692.                 gd->gd_Modify.mr_Size   = column + foundlen + (ec->CurrentLen - ec->Column);
  693.  
  694.                 msg->api_Modify = &gd->gd_Modify;
  695.  
  696.                 msg->api_Refresh |= API_REFRESH_LINE;
  697.  
  698.                 retval = RC_OK;
  699.             }
  700.         }
  701.     }
  702.  
  703.     return retval;
  704. }
  705. /*FE*/
  706.  
  707. /* -------------------------- support functions --------------------------- */
  708.  
  709. /*FS*/BOOL send_rexxcommand(struct GlobalData *gd,STRPTR cmd)
  710. {
  711.     struct MsgPort *rexxport;
  712.  
  713.     Forbid();
  714.  
  715.     if((rexxport = FindPort(gd->gd_GoldEDHost)))
  716.     {
  717.         struct RexxMsg *rxmsg;
  718.         struct RexxMsg *answer;
  719.  
  720.         if((rxmsg = CreateRexxMsg(gd->gd_RexxPort, NULL, NULL)) != NULL)
  721.         {
  722.             if((rxmsg->rm_Args[0] = CreateArgstring(cmd, strlen(cmd))) != NULL)
  723.             {
  724.                 rxmsg->rm_Action = RXCOMM | RXFF_RESULT;
  725.  
  726.                 PutMsg(rexxport, &rxmsg->rm_Node);
  727.  
  728.                 do
  729.                 {
  730.                     WaitPort(gd->gd_RexxPort);
  731.  
  732.                     if((answer = (struct RexxMsg *) GetMsg(gd->gd_RexxPort)))
  733.                          gd->gd_Result = answer->rm_Result1;
  734.  
  735.                 } while (!answer);
  736.  
  737.                 Permit();
  738.  
  739.                 if(answer->rm_Result1 == RC_OK)
  740.                 {
  741.                     if(answer->rm_Result2)
  742.                     {
  743.                         if(gd->gd_Buffer)
  744.                              strcpy(gd->gd_Buffer, (char *)answer->rm_Result2);
  745.  
  746.                         DeleteArgstring((char *)answer->rm_Result2);
  747.                     }
  748.                 }
  749.  
  750.                 DeleteArgstring((char *)ARG0(answer));
  751.  
  752.                 DeleteRexxMsg(answer);
  753.  
  754.                 return(TRUE);
  755.             }
  756.         }
  757.     }
  758.  
  759.     Permit();
  760.  
  761.     return(FALSE);
  762. }
  763. /*FE*/
  764. /*FS*/ BOOL alloc_name(struct GlobalData *gd,STRPTR name,LONG len)
  765. {
  766.     struct Node *node;
  767.     BOOL rc = FALSE;
  768.  
  769.     for(node = gd->gd_FoundList.lh_Head ; node->ln_Succ != NULL ; node = node->ln_Succ)
  770.         if(node->ln_Type == len && !strncmp(node->ln_Name,name,len))
  771.             break;
  772.  
  773.     if(node->ln_Succ == NULL)
  774.         if((node = AsmAllocPooled(gd->gd_FoundPool,sizeof(struct Node) + len + 1,SysBase)) != NULL)
  775.         {
  776.             node->ln_Name = (STRPTR) (node + 1);
  777.             node->ln_Type = len;
  778.  
  779.             strncpy(node->ln_Name,name,len);
  780.  
  781.             AddTail(&gd->gd_FoundList,node);
  782.  
  783.             rc = TRUE;
  784.           DB(("allocated : %s\n",node->ln_Name));
  785.         }
  786.  
  787.  
  788.     return rc;
  789. }
  790. /*FE*/
  791.  
  792.